Serverless Framework でクレデンシャル情報を扱う Lambda ファンクションを作成する
こんばんは! 筧 です。
はじめに
最近、Serverless Framework を使って改善業務に取り組んでいます。 取り組んでいる中で、Serverless Framework でクレデンシャル情報を扱う Lambda ファンクションを作成する方法を確認しました。 今回はこちらの方法の一つをご紹介します。
目標
AWS Secrets Manager から Slack チャンネルの Webhook URL を取得して、 Slack チャンネルにメッセージを投稿する Lambda ファンクションを Serverless Framework で作成します。
やってみた
以下の流れで作業します。
- Slack 側の準備
- AWS Secrets Manager の設定
- Serverless Framework のサービス作成
- Serverless Framework のサービスデプロイ
- 動作確認
1. Slack 側の準備
Incoming Webhook の設定
次のページを参考に Incoming Webhook の設定をしてください。
https://hooks.slack.com/services/XXX/YYY/ZZZ
のような形式の Webhook URL を確認しておきます。
2. AWS Secrets Manager の設定
マネジメントコンソールから確認した Slack のクレデンシャル情報を登録します。
- SLACK_WEBHOOK_URL:確認した Webhook URL
シークレットの名前を付けます。ここでは、dev/slack とします。
今回は自動ローテーションは不要なので、自動ローテーションを無効にするにチェック入れます。
シークレットが正常に保存されれば OK です。
3. Serverless Framework のサービス作成
Serverless Framework 実行環境構築は省略します。 構築方法は以下を参照ください。
初めてのサーバーレスアプリケーション開発 ~Serverless Framework を使ってAWSリソースをデプロイする~ -> Serverless Framework実行環境構築
サービス作成
Serverless Framework のサービスを作成します。 今回は slack-post-serviceというサービス名で、Python 3.8の Lambda ファンクションを作成します。
$ serverless create --template aws-python3 --path slack-post-service Serverless: Generating boilerplate... Serverless: Generating boilerplate in "{省略}" _______ __ | _ .-----.----.--.--.-----.----| .-----.-----.-----. | |___| -__| _| | | -__| _| | -__|__ --|__ --| |____ |_____|__| \___/|_____|__| |__|_____|_____|_____| | | | The Serverless Application Framework | | serverless.com, v1.72.0 -------' Serverless: Successfully generated boilerplate for template: "aws-python3"
プラグインインストール
この後登場する Lambda ファンクションで用いる外部モジュールの為に必要なプラグイン(serverless-python-requirements)をインストールします。
$ sls plugin install -n serverless-python-requirements
serverless.yml の編集
serverless.yml でサービスを定義します。
service: slack-post-service provider: name: aws runtime: python3.8 region: ap-northeast-1 profile: ${opt:profile, "default"} iamRoleStatements: - Effect: Allow Action: - secretsmanager:GetSecretValue Resource: - "*" plugins: - serverless-python-requirements functions: post_content: handler: handler.post_content environment: SECRET_NAME: dev/slack
ハイライトの箇所がポイントです。
- iamRoleStatements で AWS Secrets Manager へのアクセスを許可しています(必要に応じて Resource を絞ってください)
- Lambda ファンクションの環境変数として、作成したシークレットの名前を記載
handler.py の編集
handler.py で Slack にメッセージを POST する Lambda ファンクションを作成します。
import os import boto3 import json import requests # Get credentials secret_name = os.environ['SECRET_NAME'] secretsmanager_client = boto3.client('secretsmanager', region_name='ap-northeast-1') resp = secretsmanager_client.get_secret_value(SecretId=secret_name) secret = json.loads(resp['SecretString']) SLACK_WEBHOOK_URL = secret['SLACK_WEBHOOK_URL'] def post_content(event, context): payload = { "text": "テスト投稿" } content = json.dumps(payload) response = requests.post(SLACK_WEBHOOK_URL, data=content) return
ハイライトの箇所がポイントです。
- serverless.yml で設定した Lambda ファンクションの環境変数からシークレットの名前を取得
- シークレットの名前を元にクレデンシャル情報(Webhook URL)を取得
4. Serverless Framework のサービスデプロイ
デプロイ
サービスをデプロイします。
$ cd slack-post-service/ $ sls deploy -v {省略}
5. 動作確認
Lambda ファンクションを実行する
デプロイされたLambdaファンクションを実行します。
sls invoke -f post_content
対象の Slack を確認すると、メッセージが投稿されていることが確認できました!
おわりに
誰かの参考になると幸いです。それでは良い夜を!
更新履歴
- プラグインのインストール方法を変更しました(2020/10/16)